using Microsoft.EntityFrameworkCore;
using PandaWebAPI.Models.ef;

namespace PandaWebAPI.Services;

/// <summary>
/// 验证码服务实现
/// </summary>
public class VerificationCodeService : IVerificationCodeService
{
    private readonly PandaSystemContext _context;

    public VerificationCodeService(PandaSystemContext context)
    {
        _context = context;
    }

    /// <inheritdoc />
    public async Task<IEnumerable<VerificationCode>> GetAllAsync()
    {
        return await _context.VerificationCodes
            .Include(vc => vc.User)
            .ToListAsync();
    }

    /// <inheritdoc />
    public async Task<VerificationCode?> GetByIdAsync(Guid id)
    {
        return await _context.VerificationCodes
            .Include(vc => vc.User)
            .FirstOrDefaultAsync(vc => vc.CodeId == id);
    }

    /// <inheritdoc />
    public async Task<VerificationCode?> GetByUserIdAsync(Guid userId)
    {
        return await _context.VerificationCodes
            .Include(vc => vc.User)
            .FirstOrDefaultAsync(vc => vc.UserId == userId);
    }

    /// <inheritdoc />
    public async Task<VerificationCode> CreateAsync(VerificationCode verificationCode)
    {
        verificationCode.CodeId = Guid.NewGuid();
        verificationCode.IsUsed = false;
        _context.VerificationCodes.Add(verificationCode);
        await _context.SaveChangesAsync();
        return verificationCode;
    }

    /// <inheritdoc />
    public async Task<VerificationCode> UpdateAsync(VerificationCode verificationCode)
    {
        _context.Entry(verificationCode).State = EntityState.Modified;
        await _context.SaveChangesAsync();
        return verificationCode;
    }

    /// <inheritdoc />
    public async Task DeleteAsync(Guid id)
    {
        var verificationCode = await _context.VerificationCodes.FindAsync(id);
        if (verificationCode != null)
        {
            _context.VerificationCodes.Remove(verificationCode);
            await _context.SaveChangesAsync();
        }
    }

    /// <inheritdoc />
    public async Task<bool> VerifyCodeAsync(string code, byte codeType, Guid? userId = null)
    {
        var verificationCode = await _context.VerificationCodes
            .FirstOrDefaultAsync(vc => 
                vc.Code == code && 
                vc.CodeType == codeType && 
                vc.ExpiryTime > DateTime.UtcNow &&
                vc.IsUsed != true &&
                (userId == null || vc.UserId == userId));

        return verificationCode != null;
    }

    /// <inheritdoc />
    public async Task MarkAsUsedAsync(Guid codeId)
    {
        var verificationCode = await _context.VerificationCodes.FindAsync(codeId);
        if (verificationCode != null)
        {
            verificationCode.IsUsed = true;
            await _context.SaveChangesAsync();
        }
    }
} 